/**
 * DataCleaner (community edition)
 * Copyright (C) 2014 Free Software Foundation, Inc.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.datacleaner.descriptors;

import java.util.Collection;
import java.util.Set;

import org.datacleaner.api.Alias;
import org.datacleaner.api.Analyzer;
import org.datacleaner.api.ComponentSuperCategory;
import org.datacleaner.api.Filter;
import org.datacleaner.api.Renderer;
import org.datacleaner.api.RenderingFormat;
import org.datacleaner.api.Transformer;
import org.datacleaner.job.AnalysisJob;

/**
 * An interface for an object that provide descriptors for components such as
 * {@link Analyzer}, {@link Transformer}s and {@link Filter}s.
 * 对象的接口，为{@link Analyzer}，{@ link Transformer}和{@link Filter}等组件提供描述符。
 *
 * The {@link DescriptorProvider} is used heavily when reading/parsing
 * {@link AnalysisJob}s coming from e.g. XML files or other serialized formats.
 * 在读取/解析{@link AnalysisJob}时，{@link DescriptorProvider}被大量使用，
 * 例如XML文件或其他序列化格式。
 *
 * Many of the descriptors provided by this class can also be generated by the
 * <b>Descriptors</b> class' helper methods. It is however advised to use the
 * {@link DescriptorProvider} since it keeps a proper registry of descriptors
 * used, and reuses existing descriptor definitions.
 * 此类提供的许多描述符也可以通过 Descriptors 类的辅助方法来生成。
 * 但是，建议使用{@link DescriptorProvider}，因为它会保留使用的描述符的正确注册表，
 * 并重用现有的描述符定义。
 */
public interface DescriptorProvider {

    /**
     * Refreshes the descriptor list.
     */
    void refresh();

    /**
     * Gets a {@link ComponentDescriptor} by it's display name (or secondly by
     * searching using {@link Alias}es).
     *
     * @param name
     * @return
     */
    ComponentDescriptor<?> getComponentDescriptorByDisplayName(String name);

    /**
     * Gets all the {@link AnalyzerDescriptor}s currently registered.
     *
     * @return
     */
    Collection<AnalyzerDescriptor<?>> getAnalyzerDescriptors();

    /**
     * Gets a {@link AnalyzerDescriptor} by its {@link Analyzer} class.
     *
     * @param analyzerClass
     * @return
     */
    <A extends Analyzer<?>> AnalyzerDescriptor<A> getAnalyzerDescriptorForClass(Class<A> analyzerClass);

    /**
     * Gets a {@link AnalyzerDescriptor} by its display name (or secondly by
     * searching using {@link Alias}es).
     *
     * @param name
     * @return
     */
    AnalyzerDescriptor<?> getAnalyzerDescriptorByDisplayName(String name);

    /**
     * Gets all {@link TransformerDescriptor}s currently registered.
     *
     * @return
     */
    Collection<TransformerDescriptor<?>> getTransformerDescriptors();

    /**
     * Gets a {@link TransformerDescriptor} by its {@link Transformer} class.
     *
     * @param transformerClass
     * @return
     */
    <T extends Transformer> TransformerDescriptor<T> getTransformerDescriptorForClass(Class<T> transformerClass);

    /**
     * Gets a {@link TransformerDescriptor} by its display name (or secondly by
     * searching using {@link Alias}es).
     *
     * @param name
     * @return
     */
    TransformerDescriptor<?> getTransformerDescriptorByDisplayName(String name);

    /**
     * Gets all {@link FilterDescriptor}s currently registered.
     *
     * @return
     */
    Collection<FilterDescriptor<?, ?>> getFilterDescriptors();

    /**
     * Gets a {@link FilterDescriptor} by its {@link Filter} class.
     *
     * @param filterClass
     * @return
     */
    <F extends Filter<C>, C extends Enum<C>> FilterDescriptor<F, C> getFilterDescriptorForClass(Class<F> filterClass);

    /**
     * Gets a {@link FilterDescriptor} by its display name (or secondly by
     * searching using {@link Alias}es).
     *
     * @param name
     * @return
     */
    FilterDescriptor<?, ?> getFilterDescriptorByDisplayName(String name);

    /**
     * Gets all the {@link ComponentSuperCategory} categories that are
     * represented in the components known to this {@link DescriptorProvider}.
     *
     * @return
     */
    Set<ComponentSuperCategory> getComponentSuperCategories();

    /**
     * Gets all the {@link ComponentDescriptor}s known to this
     * {@link DescriptorProvider}
     *
     * @return
     */
    Collection<? extends ComponentDescriptor<?>> getComponentDescriptors();

    /**
     * Gets all the {@link ComponentDescriptor}s known to this
     * {@link DescriptorProvider} that are categories as per the provided
     * {@link ComponentSuperCategory}.
     *
     * @param category
     * @return
     */
    Collection<? extends ComponentDescriptor<?>> getComponentDescriptorsOfSuperCategory(
            ComponentSuperCategory category);

    /**
     * Gets all {@link RendererBeanDescriptor}s currently registered.
     *
     * @return
     */
    Collection<RendererBeanDescriptor<?>> getRendererBeanDescriptors();

    /**
     * Gets a {@link RendererBeanDescriptor} by its {@link Renderer} class.
     *
     * @param rendererBeanClass
     * @return
     */
    <R extends Renderer<?, ?>> RendererBeanDescriptor<R> getRendererBeanDescriptorForClass(Class<R> rendererBeanClass);

    /**
     * Gets all {@link RendererBeanDescriptor}s for a specific
     * {@link RenderingFormat}.
     *
     * @param renderingFormat
     * @return
     */
    Collection<RendererBeanDescriptor<?>> getRendererBeanDescriptorsForRenderingFormat(
            Class<? extends RenderingFormat<?>> renderingFormat);

    /**
     * Add a {@link DescriptorProviderListener} that will be notified
     * if the list of descriptors change.
     *
     * @param listener
     */
    void addListener(DescriptorProviderListener listener);

    /**
     * Remove a {@link DescriptorProviderListener}
     *
     * @param listener
     */
    void removeListener(DescriptorProviderListener listener);
}
